//函子
class Container {
  static of (value) {
    return new Container(value);
  }

  constructor(value) {
    this._value = value; //存储传入值
  }

  map(fn) {
    return Container.of(fn(this._value));
  }
}

//对外部传值为空值处理,但不知道在何处发生异常
class Maybe {
  static of (value) {
    return new Maybe(value);
  }

  isNothing() {
    return !this._value;
  }

  constructor(value) {
    this._value = value;
  }

  map(fn) {
    return this.isNothing() ? this : Maybe.of(fn(this._value));
  }
}


class Left {
  static of (value) {
    return new Left(value)
  }
  constructor(value) {
    this._value = value;
  }
  map(fn) {
    return this;
  }
}

class Right {
  static of (value) {
    return new Right(value)
  }
  constructor(value) {
    this._value = value;
  }
  map(fn) {
    return Right.of(fn(this._value));
  }
}

const fp = require('lodash/fp')
//存储不纯_value,惰性执行,存在嵌套问题
class IO {
  static of (value) {
    return new IO(function () {
      return value;
    })
  }

  constructor(fn) {
    this._value = fn;
  }

  map(fn) {
    return new IO(fp.flowRight(fn, this._value));
  }

  join() {
    return this._value();
  }

  flatMap(fn) {
    return this.map(fn).join();
  }
}

module.exports = {
  Container,
  Maybe,
  Left,
  Right,
  IO
}